package com.lintf.wxpay.controller;

import com.google.gson.Gson;
import com.lintf.common.base.AjaxResult;
import com.lintf.common.base.HttpStatus;
import com.lintf.common.page.BaseController;
import com.lintf.wxpay.base.WxChatPayDto;
import com.lintf.wxpay.base.utils.HttpUtils;
import com.lintf.wxpay.base.utils.WechatPay2ValidatorForRequest;
import com.lintf.wxpay.service.WxPayService;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author lin tingfeng
 * @system Mac
 * @data 2024/11/21 13:58
 * @package_name com.lintf.wxpay.controller
 * @project_name sharding-sphere
 * @desc
 */
@RestController
@RequestMapping("/api/wx-pay")
@Slf4j
public class WxPayController extends BaseController {

    @Autowired
    private WxPayService wxPayService;
    @Autowired
    private Verifier verifier;

    /**
     * 发起原生支付请求
     * 
     * @param dto 包含支付信息的数据传输对象
     * @return AjaxResult 包含支付结果的信息
     */
    @PostMapping("/native/pay")
    public AjaxResult nativePay(@RequestBody WxChatPayDto dto) {
        return success(wxPayService.nativePay(dto));
    }

    /**
     * 发起小程序支付请求
     * 
     * @param dto 包含支付信息的数据传输对象
     * @return AjaxResult 包含支付结果的信息
     */
    @PostMapping("/miniProgram/pay")
    public AjaxResult miniProgramPay(@RequestBody WxChatPayDto dto) {
        return success(wxPayService.miniProgramPay(dto));
    }

    /**
     * 处理退款请求
     * 
     * @param orderNo 订单号
     * @param reason  退款原因
     * @return AjaxResult 包含退款结果的信息
     * @throws IOException 可能抛出的IO异常
     */
    @GetMapping("/refunds")
    public AjaxResult refunds(String orderNo, String reason) throws IOException {
        return success(wxPayService.refunds(orderNo, reason));
    }

    /**
     * 支付回调通知处理
     * 
     * @param request  Http请求对象
     * @param response Http响应对象
     * @return String 包含处理结果的JSON字符串
     */
    @PostMapping("/pay/notify")
    public String payNotify(HttpServletRequest request, HttpServletResponse response) {
        log.info("PayNotify支付回调通知流程：开始");
        Map<String, String> resultMap = new HashMap<>();
        Gson gson = new Gson();
        try {
            // 读取请求体数据
            String body = HttpUtils.readData(request);
            HashMap<String, Object> bodyMap = gson.fromJson(body, HashMap.class);
            String requestId = String.valueOf(bodyMap.get("id"));
            log.info("PayNotify支付回调通知流程：ID==> {}", requestId);
            log.info("PayNotify支付回调通知流程：Body==> {}", bodyMap);
            // 验证签名
            log.info("PayNotify支付回调通知流程：开始验签");
            WechatPay2ValidatorForRequest wechatPay2ValidatorForRequest = new WechatPay2ValidatorForRequest(verifier,
                    requestId, body);
            if (!wechatPay2ValidatorForRequest.validate(request)) {
                // 验签失败处理
                log.error("PayNotify支付回调通知流程：验签失败");
                response.setStatus(HttpStatus.ERROR);
                resultMap.put("code", "ERROR");
                resultMap.put("message", "PayNotify支付回调通知流程：验签失败");
                return gson.toJson(resultMap);
            }
            log.error("PayNotify支付回调通知流程：验签成功");
            // 处理订单
            wxPayService.processOrder(bodyMap);
            // 成功应答
            response.setStatus(HttpStatus.SUCCESS);
            resultMap.put("code", "SUCCESS");
            resultMap.put("message", "PayNotify支付回调通知流程：应答成功");
            log.info("PayNotify支付回调通知流程：完成");
            return gson.toJson(resultMap);
        } catch (Exception e) {
            // 异常处理
            response.setStatus(HttpStatus.ERROR);
            resultMap.put("code", "ERROR");
            log.error("PayNotify支付回调通知流程：发生异常：{}", e.getMessage(), e);
            resultMap.put("message", "PayNotify支付回调通知流程：发生异常");
            return gson.toJson(resultMap);
        }
    }

    /**
     * 退款回调通知处理
     * 
     * @param request  Http请求对象
     * @param response Http响应对象
     * @return String 包含处理结果的JSON字符串
     */
    @PostMapping("/refunds/notify")
    public String refundsNotify(HttpServletRequest request, HttpServletResponse response) {
        log.info("RefundsNotify退款回调通知流程：开始");
        Map<String, String> resultMap = new HashMap<>();
        Gson gson = new Gson();
        try {
            // 读取请求体数据
            String body = HttpUtils.readData(request);
            HashMap<String, Object> bodyMap = gson.fromJson(body, HashMap.class);
            String requestId = String.valueOf(bodyMap.get("id"));
            log.info("RefundsNotify退款回调通知流程：ID==> {}", requestId);
            log.info("RefundsNotify退款回调通知流程：Body==> {}", bodyMap);
            // 验证签名
            log.info("NativePay支付回调通知：开始验签");
            WechatPay2ValidatorForRequest wechatPay2ValidatorForRequest = new WechatPay2ValidatorForRequest(verifier,
                    requestId, body);
            if (!wechatPay2ValidatorForRequest.validate(request)) {
                // 验签失败处理
                log.error("RefundsNotify退款回调通知流程：验签失败");
                response.setStatus(HttpStatus.ERROR);
                resultMap.put("code", "ERROR");
                resultMap.put("message", "RefundsNotify退款回调通知流程：验签失败");
                return gson.toJson(resultMap);
            }
            log.error("RefundsNotify退款回调通知流程：验签成功");
            // 处理退款单
            wxPayService.processRefunds(bodyMap);
            // 成功应答
            response.setStatus(HttpStatus.SUCCESS);
            resultMap.put("code", "SUCCESS");
            resultMap.put("message", "RefundsNotify退款回调通知流程：应答成功");
            log.info("RefundsNotify退款回调通知流程：完成");
            return gson.toJson(resultMap);
        } catch (Exception e) {
            // 异常处理
            response.setStatus(HttpStatus.ERROR);
            resultMap.put("code", "ERROR");
            log.error("RefundsNotify退款回调通知流程：发生异常：{}", e.getMessage(), e);
            resultMap.put("message", "RefundsNotify退款回调通知流程：发生异常");
            return gson.toJson(resultMap);
        }
    }

    /**
     * 取消订单
     * 
     * @param orderNo 订单号
     * @return AjaxResult 包含取消结果的信息
     * @throws Exception 可能抛出的异常
     */
    @GetMapping("/cancelOrder")
    public AjaxResult cancelOrder(String orderNo) throws Exception {
        wxPayService.cancelOrder(orderNo);
        return AjaxResult.success();
    }

    /**
     * 查询订单
     * 
     * @param orderNo 订单号
     * @return AjaxResult 包含订单查询结果的信息
     * @throws Exception 可能抛出的异常
     */
    @GetMapping("/queryOrder")
    public AjaxResult queryOrder(String orderNo) throws Exception {
        return AjaxResult.success(wxPayService.queryOrder(orderNo));
    }

    /**
     * 查询退款
     * 
     * @param refundNo 退款号
     * @return AjaxResult 包含退款查询结果的信息
     * @throws Exception 可能抛出的异常
     */
    @GetMapping("/queryRefunds")
    public AjaxResult queryRefunds(String refundNo) throws Exception {
        return AjaxResult.success(wxPayService.queryRefunds(refundNo));
    }

}
